﻿using FlyingCircusWebIS.Controllers.Utilidades;
using FlyingCircusWebIS.Models;
using FlyingCircusWebIS.ViewModels.CupomVM;
using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace FlyingCircusWebIS.Controllers
{
    public class CupomController : Controller
    {
        // Identificador das actions disponíveis no controller
        public const string INDEX_ACTION = "Index";
        public const string FORM_ACTION = "Form";
        public const string DESATIVAR_ACTION = "Desativar";
        public const string ATIVAR_ACTION = "Ativar";
        

        public ActionResult Index()
        {
            CupomIndexVM vm = ConstruirIndexVM();
            return View(vm);
        }


        public ActionResult Form(string codigo = null)
        {
            CupomFormVM vm;
            if (codigo != null)
            {
                vm = ConstruirFormVMParaEdicao(codigo);
                if (vm == null)
                    return new HttpNotFoundResult();
            }
            else
            {
                vm = ConstruirFormVMParaNovo();
            }

            return View(vm);
        }

        [HttpPost]
        public ActionResult Form(CupomFormVM vm)
        {
            bool edicao = vm.Edicao;
            Cupom registro = ConverterFormVM(vm);

            ValidarRegistroRegras(registro, edicao, ModelState);
            if (ModelState.IsValid)
            {
                if (edicao)
                    AtualizarRegistro(registro);
                else
                    InserirRegistro(registro);

                return RedirectToAction(INDEX_ACTION);
            }
            else
            {
                return View(vm);
            }
        }

 

        public JsonResult Desativar(string codigo)
        {
            DesativarRegistroPorCodigo(codigo);
            return Json(new JsonActionResultModel("Registro desativado com sucesso."));
        }


        public JsonResult Ativar(string codigo)
        {
            AtivarRegistroPorCodigo(codigo);
            return Json(new JsonActionResultModel("Registro ativado com sucesso."));
        }


        // -----------------------------------------------------------------------------------------
        // Métodos auxiliares 
        // -----------------------------------------------------------------------------------------

        private CupomIndexVM ConstruirIndexVM()
        {
            CupomIndexVM vm = new CupomIndexVM();
            List<Cupom> registros = ListarRegistros();
            vm.Registros = registros;
            vm.TotalRegistros = registros.Count;
            return vm;
        }

        private CupomFormVM ConstruirFormVMParaNovo()
        {
            return new CupomFormVM() { Edicao = false };
        }

        private CupomFormVM ConstruirFormVMParaEdicao(string codigo)
        {
            Cupom registro = BuscarRegistroPorCodCupom(codigo);
            if (registro != null)
            {
                CupomFormVM vm = ConverterFormVM(registro);
                vm.Edicao = true;
                return vm;
            }

            return null;
        }

        private CupomFormVM ConverterFormVM(Cupom registro)
        {
            CupomFormVM vm = new CupomFormVM();
            vm.CodCupom = registro.CodCupom;
            vm.NomeCupom = registro.NomeCupom;
            vm.Descricao = registro.Descricao;
            vm.Desconto = registro.Desconto * 100;
            vm.FlagAtivo = registro.FlagAtivo.Equals("S");
            return vm;
        }

        private Cupom ConverterFormVM(CupomFormVM vm)
        {
            Cupom registro = new Cupom();
            registro.CodCupom = vm.CodCupom;
            registro.NomeCupom = vm.NomeCupom;
            registro.Descricao = vm.Descricao;
            registro.Desconto = (vm.Desconto / 100);
            registro.FlagAtivo = (vm.FlagAtivo ? "S" : "N");
            return registro;
        }


        // Valida se o registro passado pode ser adicionado ou editado no banco de dados
        // Cada erro de validação encontrado é adiconado ao ModelState
        private void ValidarRegistroRegras(Cupom novoRegistro, bool edicao, ModelStateDictionary ModelState)
        {
            string codigoCupom = novoRegistro.CodCupom;

            if (edicao)
            {
                string nomeAlteracao = novoRegistro.NomeCupom;
                string nome = BuscarNomeRegistroPorCod(codigoCupom);
                if (!nomeAlteracao.Equals(nome, StringComparison.InvariantCultureIgnoreCase))
                {
                    if (IsNomeEmUso(nomeAlteracao))
                        ModelState.AddModelError("NomeExistente", "Já existe uma promoção com o nome informado.");
                }

            }
            else
            {

                if (IsCodigoCupomEmUso(codigoCupom))
                    ModelState.AddModelError("CodCupom", "Já existe uma promoção com o cupom informado.");
            }

        }

        private bool IsCodigoCupomEmUso(string codigo)
        {
            bool codCupomExistente = (BuscarRegistroPorCodCupom(codigo) != null);
            return codCupomExistente;
        }

        private bool IsNomeEmUso(string nome)
        {
            bool nomeExistente = (BuscarRegistroPorNome(nome) != null);
            return nomeExistente;
        }

        private string BuscarNomeRegistroPorCod(string codigo)
        {
            string nome = BuscarRegistroPorCodCupom(codigo).NomeCupom;
            return nome;

        }

        // ----------------------------------------------------------------------------------
        // Métodos auxiliares de acesso ao banco de dados.
        //
        // Os métodos abaixo se comunicam diretamente com o banco de dados.
        // ----------------------------------------------------------------------------------


        private void InserirRegistro(Cupom registro)
        {
            string sqlInserir = "insert into CUPOM (CodCupom, NomeCupom, Descricao, Desconto, DataCadastro, FlagAtivo) values (?, ?, ?, ?, ?, ?)";
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();

            // Abre a conexão
            gerenciadorConexao.Abrir();
            
            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlInserir;

            OleDbParameter pCodCupom = new OleDbParameter("CodCupom", OleDbType.VarChar);
            pCodCupom.Value = registro.CodCupom;
            comando.Parameters.Add(pCodCupom);
            
            OleDbParameter pNome = new OleDbParameter("NomeCupom", OleDbType.VarChar);
            pNome.Value = registro.NomeCupom;
            comando.Parameters.Add(pNome);

            OleDbParameter pDescricao = new OleDbParameter("Descricao", OleDbType.VarChar);
            pDescricao.Value = registro.Descricao;
            comando.Parameters.Add(pDescricao);

            OleDbParameter pDesconto = new OleDbParameter("Desconto", OleDbType.Numeric);
            pDesconto.Value = registro.Desconto;
            comando.Parameters.Add(pDesconto);

            OleDbParameter pDataCad = new OleDbParameter("DataCadastro", OleDbType.Date);
            pDataCad.Value = DateTime.Now;
            comando.Parameters.Add(pDataCad);

            OleDbParameter pFlagAtivo = new OleDbParameter("FlagAtivo", OleDbType.VarChar);
            pFlagAtivo.Value = registro.FlagAtivo;
            comando.Parameters.Add(pFlagAtivo);

            // Insert
            comando.ExecuteNonQuery();

            // Fecha a conexão
            gerenciadorConexao.Fechar();
        }

        private void AtualizarRegistro(Cupom registro)
        {
            string sqlAtualizar = "update CUPOM set NomeCupom = ?, Descricao = ?, Desconto = ?, FlagAtivo = ? where CodCupom = ?";
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();
           
            // Abre a conexão
            gerenciadorConexao.Abrir();

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;

            OleDbParameter pNome = new OleDbParameter("NomeCupom", OleDbType.VarChar);
            pNome.Value = registro.NomeCupom;
            comando.Parameters.Add(pNome);

            OleDbParameter pDescricao = new OleDbParameter("Descricao", OleDbType.VarChar);
            pDescricao.Value = registro.Descricao;
            comando.Parameters.Add(pDescricao);

            OleDbParameter pDesconto = new OleDbParameter("Desconto", OleDbType.Numeric);
            pDesconto.Value = registro.Desconto;
            comando.Parameters.Add(pDesconto);

            OleDbParameter pFlagAtivo = new OleDbParameter("FlagAtivo", OleDbType.VarChar);
            pFlagAtivo.Value = registro.FlagAtivo;
            comando.Parameters.Add(pFlagAtivo);

            OleDbParameter pCodCupom = new OleDbParameter("CodCupom", OleDbType.VarChar);
            pCodCupom.Value = registro.CodCupom;
            comando.Parameters.Add(pCodCupom);

            // Update
            comando.ExecuteNonQuery();

            // Fecha a conexão
            gerenciadorConexao.Fechar();
        }

       

        private Cupom BuscarRegistroPorCodCupom(string cupom)
        {
            Cupom registro = null;
            string sqlBuscar = "select * from CUPOM where LOWER(CodCupom) = LOWER(?)";
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();

            // Abre a conexão
            gerenciadorConexao.Abrir();

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlBuscar;

            OleDbParameter pCodCupom = new OleDbParameter("CodCupom", OleDbType.VarChar);
            pCodCupom.Value = cupom;
            comando.Parameters.Add(pCodCupom);

            // Select    
            OleDbDataReader dr = comando.ExecuteReader();
            if (dr.Read())
            {
                registro = ConverterDataReaderParaObj(dr);
            }
            
            // Fecha a conexão
            gerenciadorConexao.Fechar();
            
            return registro;
        }




        private Cupom BuscarRegistroPorNome(string nome)
        {
            Cupom registro = null;
            string sqlBuscar = "select * from CUPOM where LOWER(NomeCupom) = LOWER(?)";
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();

            // Abre a conexão
            gerenciadorConexao.Abrir();
            
            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlBuscar;

            OleDbParameter pNome = new OleDbParameter("NomeCupom", OleDbType.VarChar);
            pNome.Value = nome;
            comando.Parameters.Add(pNome);

            // Select            
            OleDbDataReader dr = comando.ExecuteReader();
            if (dr.Read())
            {
                registro = ConverterDataReaderParaObj(dr);
            }

            // Fecha a conexão
            gerenciadorConexao.Fechar();
            
            return registro;
        }

        

        private void DesativarRegistroPorCodigo(string codigo)
        {
            string sqlAtualizar = "update CUPOM set flagAtivo = 'N' where CodCupom = ?";
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();

            // Abre a conexão
            gerenciadorConexao.Abrir();

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;

            OleDbParameter pCod = new OleDbParameter("CodCupom", OleDbType.VarChar);
            pCod.Value = codigo;
            comando.Parameters.Add(pCod);
            
            // Update
            comando.ExecuteNonQuery();

            // Fecha a conexão
            gerenciadorConexao.Fechar();
        }

        private void AtivarRegistroPorCodigo(string codigo)
        {
            string sqlAtualizar = "update CUPOM set flagAtivo = 'S' where CodCupom = ?";
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();
       
            // Abre a conexão
            gerenciadorConexao.Abrir();

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;

            OleDbParameter pCod = new OleDbParameter("CodCupom", OleDbType.VarChar);
            pCod.Value = codigo;
            comando.Parameters.Add(pCod);

            // Update
            comando.ExecuteNonQuery();

            // Fecha a conexão
            gerenciadorConexao.Fechar();
        }

        private List<Cupom> ListarRegistros()
        {
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();
            String sqlConsulta = "select * from CUPOM";

            // Abre a conexão
            gerenciadorConexao.Abrir();

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlConsulta;

            // Select
            OleDbDataReader dr = comando.ExecuteReader();

            List<Cupom> registros = new List<Cupom>();
            while (dr.Read())
            {
                Cupom registro = ConverterDataReaderParaObj(dr);
                registros.Add(registro);
            }

            // Fecha a conexão
            gerenciadorConexao.Fechar();

            return registros;
        }

        private Cupom ConverterDataReaderParaObj(OleDbDataReader dr)
        {
            Cupom registro = new Cupom();
            registro.CodCupom = dr["CodCupom"].ToString();
            registro.NomeCupom = dr["NomeCupom"].ToString();
            registro.Descricao = dr["Descricao"].ToString();
            registro.Desconto = Double.Parse(dr["Desconto"].ToString());
            registro.DataCadastro = DateTime.Parse(dr["DataCadastro"].ToString());
            registro.FlagAtivo = dr["FlagAtivo"].ToString();

            return registro;
        }

    

    }
}
